﻿using System;
using System.Collections.Generic;
using IterationLife.Datas;
using IterationLife.FootballTeaching.Enums;
using IterationLife.FootballTeaching.Models;
using IterationLife.FootballTeaching.Queries;
using IterationLife.FootballTeaching.Repositories;
using IterationLife.PlatformBackEnd.AppServices.Contracts.FootballTeachings;
using IterationLife.PlatformBackEnd.AppServices.Dtos.FootballTeachings;
using Util;
using Util.Applications;
using Util.Datas.Queries;
using Util.Exceptions;

namespace IterationLife.PlatformBackEnd.AppServices.Impl.FootballTeachings
{
    /// <summary>
    /// 课时服务
    /// </summary>
    public class LessonService : ApplicationServiceBase<Lesson, LessonDto, LessonQuery>, ILessonService
    {
        /// <summary>
        /// 初始化课时服务
        /// </summary>
        /// <param name="unitOfWork">工作单元</param>
        /// <param name="lessonRepository">课时仓储</param>
        /// <param name="courseRepository">课程仓储</param>
        /// <param name="chapterRepository">章节仓储</param>
        public LessonService(IApplicationUnitOfWork unitOfWork, ILessonRepository lessonRepository, ICourseRepository courseRepository, IChapterRepository chapterRepository)
            : base(unitOfWork, lessonRepository)
        {
            LessonRepository = lessonRepository;
            CourseRepository = courseRepository;
            ChapterRepository = chapterRepository;
        }

        /// <summary>
        /// 课时仓储
        /// </summary>
        protected ILessonRepository LessonRepository { get; set; }

        /// <summary>
        /// 课程仓储
        /// </summary>
        protected ICourseRepository CourseRepository { get; set; }

        /// <summary>
        /// 章节仓储
        /// </summary>
        protected IChapterRepository ChapterRepository { get; set; }

        /// <summary>
        /// 转换为数据传输对象
        /// </summary>
        /// <param name="entity">实体</param>
        protected override LessonDto ToDto(Lesson entity)
        {
            return entity.ToDto();
        }

        /// <summary>
        /// 转换为实体
        /// </summary>
        /// <param name="dto">数据传输对象</param>
        protected override Lesson ToEntity(LessonDto dto)
        {
            return dto.ToEntity();
        }

        /// <summary>
        /// 创建查询对象
        /// </summary>
        /// <param name="param">课时查询实体</param>
        protected override IQueryBase<Lesson> CreateQuery(LessonQuery param)
        {
            return new Query<Lesson>(param)
                .Filter(t => t.ChapterId == param.ChapterId)
                .Filter(t => t.Name.Contains(param.Name));
        }

        /// <summary>
        /// 新传输对象
        /// </summary>
        /// <param name="chapterId">章节编号</param>
        public LessonDto NewDto(Guid chapterId)
        {
            return new LessonDto
            {
                ChapterId = chapterId,
                Difficulty = DifficultyType.OneLevel,
                SortId = LessonRepository.GetSortId(chapterId)
            };
        }

        /// <summary>保存前操作</summary>
        /// <param name="dto">数据传输对象</param>
        protected override void SaveBefore(LessonDto dto)
        {
            if (dto.SortId == null || dto.SortId < 1)
                throw new Warning("课时数必须大于0");
            if (dto.Banner.Id.IsEmpty())
                throw new Warning("请上传封面图");
            if (dto.Video.Id.IsEmpty())
                throw new Warning("请上传视频");
            base.SaveBefore(dto);
        }

        /// <summary>添加</summary>
        protected override void Add(Lesson entity)
        {
            var chapterEntity = ChapterRepository.Find(entity.ChapterId);
            var courseEntity = CourseRepository.Find(chapterEntity.CourseId);
            courseEntity.ActionNumber += 1;
            base.Add(entity);
        }

        /// <summary>删除前操作</summary>
        /// <param name="entities">实体集合</param>
        protected override void DeleteBefore(List<Lesson> entities)
        {
            foreach (var entity in entities)
                entity.Chapter.Course.ActionNumber -= 1;
            base.DeleteBefore(entities);
        }
    }
}